package com.yuyou.train.lesson.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.yuyou.train.lesson.mapper.LessonMapper;
import com.yuyou.train.lesson.service.ILessonClassService;
import com.yuyou.train.lesson.service.ILessonClassUserRelationService;
import com.yuyou.train.lesson.service.ILessonResourceRuleFrameService;
import com.yuyou.train.lesson.service.ILessonResourceRuleRelationService;
import com.yuyou.train.lesson.service.ILessonService;
import com.yuyou.train.lesson.service.ILessonSubjectRelationService;
import com.yuyou.train.lesson.service.IResourceExamService;
import com.yuyou.train.lesson.service.IResourceQuestionService;
import com.yuyou.train.lesson.service.IResourceService;
import com.yuyou.train.lesson.service.IRuleService;
import com.yuyou.train.lesson.vo.req.ReqLessonUpdate;
import com.yuyou.train.service.api.admin.service.CommDataConfigAPI;
import com.yuyou.train.service.api.lesson.dto.LessonDetailDTO;
import com.yuyou.train.service.api.lesson.dto.LessonSubjectRelationDTO;
import com.yuyou.train.service.api.lesson.dto.LessonTreeDTO;
import com.yuyou.train.service.api.lesson.dto.ResourceDetailDTO;
import com.yuyou.train.service.api.lesson.entity.Lesson;
import com.yuyou.train.service.api.lesson.entity.LessonClass;
import com.yuyou.train.service.api.lesson.entity.LessonResourceRuleFrame;
import com.yuyou.train.service.api.lesson.entity.LessonResourceRuleRelation;
import com.yuyou.train.service.api.lesson.entity.LessonSubjectRelation;
import com.yuyou.train.service.api.lesson.entity.Rule;
import com.yuyou.train.service.api.user.service.UserAPI;
import com.yuyou.train.service.api.user.service.UserHwAPI;
import com.yuyou.train.service.api.user.service.UserLessonProgressAPI;
import com.yuyou.train.service.api.user.service.UserThoughtsAPI;
import com.yuyou.train.util.bean.ResBoolSimpleInfo;
import com.yuyou.train.util.bean.SortInfo;
import com.yuyou.train.util.constant.lesson.LessonCons;
import com.yuyou.train.util.enums.CommEnums;
import com.yuyou.train.util.enums.lesson.LessonEnums;
import com.yuyou.train.util.message.lesson.LessonMess;
import com.yuyou.train.util.tool.DefindBeanUtils;
import com.yuyou.train.util.tool.Sequence;
import com.yuyou.train.util.tool.UUIDUtil;

@Service
public class LessonServiceImpl implements ILessonService{

	@Autowired
	private LessonMapper lessonMapper;
	
	@Autowired
	private ILessonClassService lessonClassService;
	
	@Autowired
	private ILessonClassUserRelationService iLessonClassUserRelationService;
	
	@Autowired
	private ILessonResourceRuleFrameService lesResRulFraService;
	
	@Autowired
	private ILessonResourceRuleRelationService lesResRulRelService;
	
	@Autowired
	private ILessonSubjectRelationService lesSubRelService;
	
	@Autowired
	private IResourceService resourceService;
	
	@Autowired
	private IRuleService ruleService;
	
	@Autowired
	private IResourceExamService examService;
	
	@Autowired
	private IResourceQuestionService questionService;
	
	@Autowired
	private UserAPI userAPI;
	
	@Autowired
	private UserThoughtsAPI userThoughtsAPI;
	
	@Autowired
	private UserHwAPI userHwAPI;
	
	@Autowired
	private UserLessonProgressAPI userLessonProgressAPI;
	
	@Autowired
	CommDataConfigAPI commDataConfigAPI;

	
	
	@Override
	public int deleteByPrimaryKey(String id) {
		return lessonMapper.deleteByPrimaryKey(id);
	}

	@Override
	public int insert(Lesson record) {
		record.setId(Sequence.getSequence().getNextId());
		record.setCreateTime(new Date());
		return lessonMapper.insert(record);
	}

	@Override
	public Lesson selectByPrimaryKey(String id) {
		return lessonMapper.selectByPrimaryKey(id);
	}

	@Override
	public int updateByPrimaryKeySelective(Lesson record) {
		return lessonMapper.updateByPrimaryKeySelective(record);
	}

	@Override
	@Transactional(timeout=60)
	public ResBoolSimpleInfo<String> delLesson(String id) throws Exception {
		
		//课程启用不能修改
		ResBoolSimpleInfo<String> isLessUse=isLessonUse(id);
		if(!isLessUse.isSuccess()){
			return isLessUse;
		}
		
		//有下级不能删除
		List<Lesson> lessList=this.findByParentId(id);
		if(lessList.size()>0){
			return new ResBoolSimpleInfo<String>(false,LessonMess.ERR_DEL_IS_PAR);
		}
		
//		//有资源规则关系不能删除
//		LessonResourceRuleRelation res=new LessonResourceRuleRelation();
//		res.setLessonId(id);
//		List<LessonResourceRuleRelation> resList=lesResRulRelService.findLesResRuleRel(res);
//		if(resList.size()>0){
//			return new ResBoolSimpleInfo<String>(false,LessonMess.ERR_DEL_HAS_RESOURCE);
//		}
		//用户学习过可以删除,用户与课程相关的数据如何处理？
//		this.deleteByPrimaryKey(id);			
		Lesson up=new Lesson();
		up.setId(id);
		up.setDel(true);
		this.updateByPrimaryKeySelective(up);	
		
		//清除资源规则关系d
		cleanResRulRel(id);
		
		//假如用户过程进程状态为01学习中，怎么处理？04：审核中怎么处理？
		lesResRulRelService.delAuditUserLesson(id);
				
		return ResBoolSimpleInfo.getSuccessInfo();
	}

	private void cleanResRulRel(String lessonId){
		//清除资源规则关系d
		lesResRulRelService.deleteByLessonId(lessonId);
		lesResRulFraService.deleteByLessonId(lessonId);
	}
	
	
	@Override
	@Transactional(timeout=60)
	public ResBoolSimpleInfo<Lesson> addLesson(String id, String name) throws Exception {
		
		ResBoolSimpleInfo<Lesson> res=new ResBoolSimpleInfo<Lesson>();
		//课程启用不能修改
		ResBoolSimpleInfo<String> isLessUse=isLessonUse(id);
		if(!isLessUse.isSuccess()){
			res.setSuccess(false);
			res.setMessage(isLessUse.getMessage());
			return res;
		}
		
		Lesson lesson=new Lesson();
		lesson.setName(name);
		LessonClass _class=lessonClassService.selectByPrimaryKey(id);
		if(_class !=null){
			//一级课程
			lesson.setLessonClassId(id);
			Long sort=getNextLessonSort(id,null,1);
			lesson.setSort(sort);
			lesson.setIsLeaf(CommEnums.isLeaf.no.getValue());	
			lesson.setLevel(1);
		}else{
			Lesson parentLess=this.selectByPrimaryKey(id);
			if(parentLess.getIsLeaf().equals(CommEnums.isLeaf.yes.getValue())){
				//叶子不能新增下级
				return new ResBoolSimpleInfo<Lesson>(false,LessonMess.ERR_ADD_IS_LEAF);
			}
			//二级课程
			lesson.setLessonClassId(parentLess.getLessonClassId());
			Long sort=getNextLessonSort(parentLess.getLessonClassId(),parentLess.getId(),2);
			lesson.setParentId(parentLess.getId());
			lesson.setSort(sort);
			lesson.setIsLeaf(CommEnums.isLeaf.yes.getValue());
			lesson.setLevel(2);
		}
		
		//课程启用不能修改
		LessonClass lessonClass=lessonClassService.selectByPrimaryKey(lesson.getLessonClassId());
		if(lessonClass.getIsUse().equals(CommEnums.isUse.yes.getValue())){
			res.setSuccess(false);
			res.setMessage(String.format(LessonMess.ERR_LESSON_USE_UPDATE, lessonClass.getName()));
			return res;
		}
				
		lesson.setScore(0);
		lesson.setMark(0);
		lesson.setAttr(LessonEnums.attr.comm.getValue());
		lesson.setDel(false);
		this.insert(lesson);
		
		return new ResBoolSimpleInfo<Lesson>(true, null , lesson);
	}

	
	@Override
	public ResBoolSimpleInfo<Lesson> updateLessonName(String id, String name){
		
		ResBoolSimpleInfo<Lesson> res=new ResBoolSimpleInfo<Lesson>();	
		//课程启用不能修改
		ResBoolSimpleInfo<String> isLessUse=isLessonUse(id);
		if(!isLessUse.isSuccess()){
			res.setSuccess(false);
			res.setMessage(isLessUse.getMessage());
			return res;
		}
		
		Lesson lesson = new Lesson();
		lesson.setId(id);
		lesson.setName(name);
		this.updateByPrimaryKeySelective(lesson);
		return new ResBoolSimpleInfo<Lesson>(true, null , lesson);
	}
	
	@Override
	@Transactional(timeout=60)
	public Long getNextLessonSort(String classId,String parentId,int level) throws Exception {
		Long sort=null;
		if(level==1){
			sort=lessonMapper.getMinLessonSort(classId,null,null);
			if(sort==null){
				sort=SortInfo.MaxSort;
				return sort;
			}
		}else{
			sort=lessonMapper.getMinLessonSort(null,parentId,null);
			if(sort==null){
				sort=lessonMapper.getMinLessonSort(null,null,parentId);
			}
		}		
		String sortVer=String.valueOf(sort);
		if(sortVer.length()<SortInfo.SortLength){
			throw new Exception(SortInfo.MESS_ERR_LENGTH);
		}
		String level1=sortVer.substring(0,4);
		String level2=sortVer.substring(4,8);
		
		if(level1.equals(SortInfo.Level1Min) || level2.equals(SortInfo.Level2Min)){
			throw new Exception(SortInfo.MESS_ERR_LENGTH);
		}
		
		if(sort!=null && level==1){
			sort=sort-10000;
		}else if(sort!=null && level==2){
			sort=sort-1;
		}
		return sort;
	}
	
	
	
	@Override
	public List<Lesson> findByClassId(String classId) {
		return lessonMapper.findByClassId(classId);
	}

	@Override
	public List<Lesson> findByParentId(String parentId) {
		return lessonMapper.findByParentId(parentId);
	}


	@Override
	@Transactional(timeout=60)
	public ResBoolSimpleInfo<Lesson> updateLessonAndRel(ReqLessonUpdate reqLessonUpdate) {
		ResBoolSimpleInfo<Lesson> res=this.updateLesson(reqLessonUpdate);
		if(!res.isSuccess()){
			//目前前端更新基本信息和关系在两个接口
			cleanResRulRel(reqLessonUpdate.getId());
		}
		return res;
	}
	
	@Override
	@Transactional(timeout=60)
	public ResBoolSimpleInfo<Lesson> updateLesson(ReqLessonUpdate reqLessonUpdate) {
		ResBoolSimpleInfo<Lesson> res=new ResBoolSimpleInfo<Lesson>();
		Lesson upLesson=new Lesson();	
		
		//课程启用不能修改
		ResBoolSimpleInfo<String> isLessUse=isLessonUse(reqLessonUpdate.getId());
		if(!isLessUse.isSuccess()){
			res.setSuccess(false);
			res.setMessage(isLessUse.getMessage());
			return res;
		}
		
		//假如是考核节点，resource_type必须是05：作业（自评作业），规则必须要老师打分	
		if(reqLessonUpdate.getAttr()!=null && reqLessonUpdate.getAttr().equals(LessonEnums.attr.check.getValue())){
			//找出资源规则
			LessonResourceRuleRelation rel=lesResRulRelService.selectByLessonId(reqLessonUpdate.getId());
			if(rel !=null){
				ResourceDetailDTO resource=resourceService.selectByPrimaryKey(rel.getResourceId());
				if(!resource.getResourceType().equals(CommEnums.resourceType.hwNeedComment.getValue())){
					res.setSuccess(false);
					res.setMessage(LessonMess.ERR_UPDATE_ATTR_CHECK);
					return res;
				}
				
				Rule rule=ruleService.selectByPrimaryKey(rel.getRuleId());
				if(rule.getNeedScore()==null){
					res.setSuccess(false);
					res.setMessage(LessonMess.ERR_UPDATE_ATTR_CHECK);
					return res;
				}
			}		
		}
		
		
		
		
		
		Lesson serlesson=this.selectByPrimaryKey(reqLessonUpdate.getId());
		
		//一级科目
		if(serlesson.getIsLeaf().equals(CommEnums.isLeaf.no.getValue())){
			if(CollectionUtils.isEmpty(reqLessonUpdate.getSubjectIdList())){
				res.setSuccess(false);
				res.setMessage(LessonMess.ERR_EMPTY_SUBJECT);
				return res;
			}
			//一级才有科目	
			lesSubRelService.updateLesSubRel(reqLessonUpdate.getId(),reqLessonUpdate.getSubjectIdList());
			
			if(reqLessonUpdate.getMark()==null){
				res.setSuccess(false);
				res.setMessage(LessonMess.ERR_EMPTY_MARK);
				return res;
			}
			
			//绩点判断
			if(reqLessonUpdate.getMark()>LessonCons.LESSON_MARK_MAX || reqLessonUpdate.getMark()<LessonCons.LESSON_MARK_MIN){
				res.setSuccess(false);
				res.setMessage(LessonMess.ERR_MARK_RANGE);
				return res;
			}		
		}
		//二级科目
		else{
			//节点属性
			if(StringUtils.isEmpty(reqLessonUpdate.getAttr())){
				res.setSuccess(false);
				res.setMessage(LessonMess.ERR_EMPTY_ATTR);
				return res;
			}
			//一级只能配置一个二级节点属性
			if(reqLessonUpdate.getAttr().equals(LessonEnums.attr.check.getValue())){
				Lesson conditionLe=new Lesson();
				conditionLe.setParentId(serlesson.getParentId());
				conditionLe.setAttr(LessonEnums.attr.check.getValue());
				conditionLe.setDel(false);
				List<Lesson> checkList=this.findLessons(conditionLe,Arrays.asList(reqLessonUpdate.getId()));
				if(checkList.size()>0){
					res.setSuccess(false);
					res.setMessage(LessonMess.ERR_TOO_MUCH_ATTR);
					return res;
				}
				
				LessonResourceRuleRelation r=lesResRulRelService.selectByLessonId(reqLessonUpdate.getId());
				ResourceDetailDTO resourceDetailDTO=resourceService.selectByPrimaryKey(r.getResourceId());
				if(resourceDetailDTO !=null && !resourceDetailDTO.getResourceType().equals(CommEnums.resourceType.hwNeedComment.getValue())){
					res.setSuccess(false);
					res.setMessage(LessonMess.ERR_ATTR_RESOURCE_TYPE);
					return res;
				}
				
				
				
			}
					
			upLesson.setAttr(reqLessonUpdate.getAttr());
			
			
			//找到父科目更新科目
			Lesson p=this.selectByPrimaryKey(serlesson.getParentId());			
			List<LessonSubjectRelationDTO> pSubjectList=lesSubRelService.findBylessonId(p.getId());			
			lesSubRelService.deleteByLessonId(serlesson.getId());			
			for(LessonSubjectRelationDTO sub:pSubjectList){
				LessonSubjectRelation le=new LessonSubjectRelation();
				le.setLessonId(serlesson.getId());
				le.setDataSubject(sub.getDataSubject());
				lesSubRelService.insert(le);
			}
			
		}	
		
		upLesson.setId(reqLessonUpdate.getId());
		upLesson.setContent(reqLessonUpdate.getContent());
		upLesson.setScore(reqLessonUpdate.getScore());
		upLesson.setMark(reqLessonUpdate.getMark());

		
		
		//默认值
		if(reqLessonUpdate.getScore()==null){
			upLesson.setScore(0);
		}	
		if(reqLessonUpdate.getMark()==null){
			upLesson.setMark(0);
		}		
		
		//科目
		
		this.updateByPrimaryKeySelective(upLesson);		
		return new ResBoolSimpleInfo<Lesson>(true, null , upLesson);
	}

	@Override
	public List<LessonTreeDTO> lessonTree(String classId) {
		List<LessonTreeDTO> respLessonList = new ArrayList<>();

		LessonClass lessonClass = lessonClassService.selectByPrimaryKey(classId);
		LessonTreeDTO respClass = new LessonTreeDTO();
		respClass.setId(lessonClass.getId());
		respClass.setName(lessonClass.getName());
		respClass.setLessonClassId(lessonClass.getId());
		respClass.setLevel(0);
		respLessonList.add(respClass);

		List<LessonTreeDTO> lessonTreeList = new ArrayList<>();
		List<Lesson> lessonList = this.findByClassId(classId);
		for(Lesson lesson : lessonList){
			LessonTreeDTO respLesson = new LessonTreeDTO();
			DefindBeanUtils.copyProperties(lesson, respLesson);
			lessonTreeList.add(respLesson);
		}
		respClass.setChildren(toLessonTreeDTO(lessonTreeList, null));
		return respLessonList;
	}


	private List<LessonTreeDTO> toLessonTreeDTO(List<LessonTreeDTO> lessonTreeList , String parentId){
		// 返回DTO
		List<LessonTreeDTO> lessonTreeListRet = new ArrayList<>();
		for(LessonTreeDTO lessonTreeDTO : lessonTreeList){
			if(lessonTreeDTO.getParentId() == parentId || (lessonTreeDTO.getParentId() !=null && lessonTreeDTO.getParentId().equals(parentId))){
				lessonTreeListRet.add(lessonTreeDTO);
				List<LessonTreeDTO> children = toLessonTreeDTO(lessonTreeList, lessonTreeDTO.getId());
				lessonTreeDTO.setChildren(children);
			}
		}

		return lessonTreeListRet;
	}

	@Override
	public LessonDetailDTO detailLesson(String id) {
		LessonDetailDTO ldd = new LessonDetailDTO();
		Lesson lesson = this.selectByPrimaryKey(id);
		DefindBeanUtils.copyProperties(lesson, ldd);
		
		//课程科目IDList
		List<String> subjectIdList=new ArrayList<String>();
		List<LessonSubjectRelationDTO> list = lesSubRelService.findBylessonId(id);
		for(LessonSubjectRelationDTO subject:list){
			subjectIdList.add(subject.getSubjectId());
		}
		ldd.setSubjectIdList(subjectIdList);
		
		if(lesson.getIsLeaf().equals(CommEnums.isLeaf.yes.getValue())){
									
			//课程资源规则
			LessonResourceRuleRelation lesRes = lesResRulRelService.selectByLessonId(id);
			if(null != lesRes){
				ldd.setResourceId(lesRes.getResourceId());
				ldd.setRuleId(lesRes.getRuleId());
			}

			ResourceDetailDTO resourceDetail = resourceService.selectByPrimaryKey(ldd.getResourceId());
			if(null != resourceDetail){
				ldd.setResourceType(resourceDetail.getResourceType());
			}

			//课程视频帧
			List<LessonResourceRuleFrame> fraList=lesResRulFraService.findFrameByLessonId(id);
			if(null != fraList && !fraList.isEmpty()){
				ldd.setLesResRulFra(fraList);
			}

			//视频时长
			if(lesRes!=null){
				ResourceDetailDTO resource=resourceService.selectByPrimaryKey(lesRes.getResourceId());
				ldd.setTime(resource.getTime());
			}
		
		}			
		return ldd;
	}

	@Override
	public ResBoolSimpleInfo<String> isLessonUse(String lessonId) {
		ResBoolSimpleInfo<String> res=new ResBoolSimpleInfo<String>();
		Lesson lesson=this.selectByPrimaryKey(lessonId);
		if(lesson !=null){
			LessonClass lessonClass=lessonClassService.selectByPrimaryKey(lesson.getLessonClassId());
			if(lessonClass.getIsUse().equals(CommEnums.isUse.yes.getValue())){
				res.setSuccess(false);
				res.setMessage(String.format(LessonMess.ERR_LESSON_USE_UPDATE, lessonClass.getName()));
				return res;
			}
		}
		return ResBoolSimpleInfo.getSuccessInfo();
	}

	@Override
	public List<Lesson> findLessons(Lesson lesson, List<String> noContainIds) {
		return lessonMapper.findLessons(lesson, noContainIds);
	}

	@Override
	public List<Lesson> findSubjectLesson(String lessonClassId, String subjectId) {
		return lessonMapper.findSubjectLesson(lessonClassId, subjectId);
	}

	@Override
	public List<Lesson> findLessLesson(String lessonClassId, String subjectId,
			Long sort) {
		return lessonMapper.findLessLesson(lessonClassId, subjectId, sort);
	}




}